package com.mbbmap.security.action;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import org.json.simple.*;

import com.mbbmap.app.home.SecAccessHome;
import com.mbbmap.app.home.SecGroupHome;
import com.mbbmap.app.home.SecUsersHome;
import com.mbbmap.app.manager.ConfigManager;
import com.mbbmap.security.dao.SecGroupLevelDao;
import com.mbbmap.security.dao.SecGroupsDao;
import com.mbbmap.security.dao.SecUserDao;
import com.mbbmap.util.Constants;
import com.mbbmap.util.EncryptionHelper;

/**
 * <code>CommonDispatchAction</code> is an abstract class that extends the
 * <code>org.apache.struts.actions.DispatchAction</code> class. It automatically
 * checks whether the user that requests this action has been authenticated
 * already or not.
 * <p>
 * If the user has not been authenticated, he will be redirected to the Login page.
 * <p>
 * Subclasses of the <code>CommonDispatchAction</code> should implement a method
 * for each of the parameter value that is returned by the parameter named in
 * Constants.KEY_DISPATCH (must match with the <code>parameter</code> attribute
 * in the action mapping definition in struts-config.xml).
 *
 */
public abstract class CommonDispatchAction extends DispatchAction {

    /**
     * Checks that the user has already been authenticated, before calling superclass' <code>dispatchMethod</code>.
     * If the user has not been authenticated, will redirect to the Login page.
     * <p>
     * Subclasses should not override this method.
     *
     * @param mapping The ActionMapping used to select this instance
     * @param form The optional ActionForm bean for this request (if any)
     * @param request The HTTP request we are processing
     * @param response The HTTP response we are creating
     *
     * @return The ActionForward that was generated
     *
     */

     public boolean DEBUG;


  protected ActionForward dispatchMethod(ActionMapping mapping,
    ActionForm form, HttpServletRequest request,
    HttpServletResponse response, String name) {

    ActionForward forward = null;
    ActionErrors errors = new ActionErrors();

    HttpSession session = request.getSession(false);

/*    if (session == null) {
      //forward to session Timeout page
      forward = mapping.findForward("sessionTimeout");
      return forward;
    }
*/
       DEBUG =  ((Boolean)this.getServlet().getServletContext().getAttribute(Constants.DEBUG)).booleanValue();

       //forward to superclass' dispatchMethod
      try {
          // Check production flag
          if (ConfigManager.getInstance().get(Constants.PRODUCTION).equals(Constants.DB_NO)) {
              session.setAttribute(Constants.ACTION_MSG_KEY, ConfigManager.getInstance().get(Constants.MSG_LOGON_PRODUCTION_OFF));
              throw new Exception(Constants.KEY_ACTION_ERR_LOGON);
          }

          forward = super.dispatchMethod(mapping, form, request, response, name);
      } catch (Exception e) {
        //forward to global error page
        request.setAttribute(Constants.SYSTEM_ERROR, e.toString());
        e.printStackTrace();
        forward = mapping.findForward("error");
      }
      
      try {
    	  String logoutType = (String)request.getAttribute("LogOut");
    	  if(logoutType==null){
		      String remoteIPaddr = request.getRemoteAddr();
		  	  String remoteHostName = request.getRemoteHost();
		  	  String strMerchant = (String)session.getAttribute(Constants.MERCHANT_KEY);
		  	  String strLoginId = (String)session.getAttribute(Constants.LOGINID);
		  	  SecUsersHome suh = SecUsersHome.getInstance();
		  	  int success = suh.updLastActiveTimestamp(strMerchant,strLoginId,remoteIPaddr + " / " + remoteHostName);
		  	  if(success>0){
		  		System.out.println("update last active time suceeded");
		  	  }else{
		  		  System.out.println("update last active time failed");
		  	  }
      	  }
      }catch (Exception e){
    	  e.printStackTrace();
      }
  	
      System.out.println("TOKEN saved");
    saveToken(request);
    return forward;
  }
	
	
  	protected ArrayList<SecGroupsDao> userGroupList(HttpServletRequest request){
  		ArrayList<SecGroupsDao> arlSecGroupList = new ArrayList<SecGroupsDao>();
  		
  		HttpSession session = request.getSession(false);
  		String strEMerchant = (String) session.getAttribute(Constants.MERCHANT_KEY);
  		
		if ((strEMerchant != null) && (!strEMerchant.equals(""))){
			arlSecGroupList = (ArrayList<SecGroupsDao>) SecGroupHome.getInstance().findSecGroupList(strEMerchant);
			
		} else{
			System.out.println("Merchant string is invalid.");
		}
		
		
		ArrayList<SecGroupsDao> groupList = new ArrayList<SecGroupsDao>();
		
		for(SecGroupsDao ug : arlSecGroupList){
			if(ug.getGroupCode().startsWith("1001") == false){
				groupList.add(ug);
			}
		}
		
		return groupList;
  	}
  	
  	protected ArrayList<SecGroupsDao> myGroupList(HttpServletRequest request){
  		ArrayList<SecGroupsDao> arlSecGroupList = new ArrayList<SecGroupsDao>();
  		ArrayList<SecGroupLevelDao> secGroupLevelList = new ArrayList<SecGroupLevelDao>();
  		
  		HttpSession session = request.getSession(false);
  		String strEMerchant = (String) session.getAttribute(Constants.MERCHANT_KEY);
  		SecUserDao oSecUserDao = (SecUserDao) session.getAttribute(Constants.LOGGED_USER);
  		
		if ((strEMerchant != null) && (!strEMerchant.equals(""))){
			arlSecGroupList = (ArrayList<SecGroupsDao>) SecGroupHome.getInstance().findSecGroupList(strEMerchant);
			secGroupLevelList = (ArrayList<SecGroupLevelDao>) SecAccessHome.getInstance().findSecGroupLevelList(strEMerchant, oSecUserDao.getGroupCode());
	  		
		} else{
			System.out.println("Merchant string is invalid.");
		}
		
  		
  		
		ArrayList<SecGroupsDao> groupList = new ArrayList<SecGroupsDao>();
		
		for(SecGroupLevelDao lg : secGroupLevelList){
			
			if(lg.getcGroupCode().startsWith("01") || lg.getcGroupCode().startsWith("02")){
				for(SecGroupsDao ug : arlSecGroupList){
					if (ug.getGroupCode().equals(lg.getcGroupCode())){
						groupList.add(ug);
					}
				}
			}
			
			if(lg.getcGroupCode().startsWith("03")){
				if(lg.getcGroupCode().length() > 2){
					
					for(SecGroupsDao ug : arlSecGroupList){
						if (ug.getGroupCode().equals(lg.getcGroupCode())){
							groupList.add(ug);
						}
					}
				}
			}
		}
		
		return groupList;
  	}
	
  	protected void json_ok(HttpServletResponse response) throws ServletException, IOException {
    	JSONObject resp = new JSONObject();
		resp.put("status", "OK");
		
		PrintWriter out = response.getWriter();
		out.println(resp.toString());
    }
	
	protected void json_ok(HttpServletResponse response, JSONObject data) throws ServletException, IOException {
    	JSONObject resp = new JSONObject();
		resp.put("status", "OK");
		resp.putAll(data);
		
		PrintWriter out = response.getWriter();
		out.println(resp.toString());
    }
    
    protected void json_error(String msg, HttpServletResponse response) throws ServletException, IOException {
    	JSONObject resp = new JSONObject();
		resp.put("status", "ERROR");
		resp.put("message", msg);
		
		PrintWriter out = response.getWriter();
		out.println(resp.toString());
    }
	
    public static final String TRANSACTION_TOKEN_KEY = "org.apache.struts.action.TOKEN";
    
    public static String sanitize(String s) {
    	try {
    		if (s!=null && !s.equalsIgnoreCase("")){
    			
    			System.out.println("#Sanitize string:"+s);
    			
    			s=s.replaceAll("\\)","");
    			s=s.replaceAll("\\'","");
    			s=s.replaceAll("\\;","");
    			s=s.replaceAll("\\\\","");
    			//s=s.replaceAll("\\/","");
    			s=s.replaceAll("\"","");
    			s=s.replaceAll("\\=","");
    			s=s.replaceAll("\\%","");
    			s=s.replaceAll("\\#","");
    			s=s.replaceAll("\\$","");
    			s=s.replaceAll("\\*","");
    			s=s.replaceAll("\\>","");
    			s=s.replaceAll("\\<","");
    			s=s.replaceAll("\\|","");

    			s=sanitizeScript(s);
    		}
    	} catch (Exception e) {
            e.printStackTrace();
    	}
    	return s;
    }
    
    public static String sanitizePwd(String s) {
    	try {
    		if (s!=null && !s.equalsIgnoreCase("")){
    			
    			//System.out.println("#SanitizePwd string:"+s);
    			
    			s=s.replaceAll("\\)","");
    			s=s.replaceAll("\\'","");
    			s=s.replaceAll("\\;","");
    			s=s.replaceAll("\\\\","");
//    			s=s.replaceAll("\\/","");
    			s=s.replaceAll("\"","");
    			s=s.replaceAll("\\=","");
//    			s=s.replaceAll("\\%","");
//    			s=s.replaceAll("\\#","");
//    			s=s.replaceAll("\\$","");
//    			s=s.replaceAll("\\*","");
    			s=s.replaceAll("\\>","");
    			s=s.replaceAll("\\<","");
    			s=s.replaceAll("\\|","");
    			
    			s=sanitizeScript(s);
    		}
    	} catch (Exception e) {
            e.printStackTrace();
    	}
    	return s;
    }
    
    private static String sanitizeScript(String s) {
    	try {
    		if (s!=null && !s.equalsIgnoreCase("")){
    			s=s.replaceAll("script","");
    			s=s.replaceAll("SCRIPT","");
    			
    			//System.out.println("########################Sanitized result:"+s);
    		}
    	} catch (Exception e) {
            e.printStackTrace();
    	}
    	return s;
    }
	
}